home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gdevsgi.c < prev    next >
C/C++ Source or Header  |  1997-01-23  |  7KB  |  221 lines

  1. /*
  2.  * This file is distributed with Ghostscript, but its author,
  3.  * Tanmoy Bhattacharya (tanmoy@qcd.lanl.gov) hereby places it in the
  4.  * public domain.
  5.  */
  6.  
  7. /* gdevsgi.c */
  8. /* SGI raster file driver */
  9. #include "gdevprn.h"
  10. #include "gdevsgi.h"
  11.  
  12. #define X_DPI 72
  13. #define Y_DPI 72
  14.  
  15. #define sgi_prn_device(procs, dev_name, num_comp, depth, max_gray, max_color, print_page)\
  16. {prn_device_body(gx_device_printer, procs, dev_name, \
  17.          DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, X_DPI, Y_DPI, \
  18.          0, 0, 0, 0, \
  19.          num_comp, depth, max_gray, max_color, max_gray+1, max_color+1, \
  20.          print_page)}
  21.  
  22. private dev_proc_map_rgb_color(sgi_map_rgb_color);
  23. private dev_proc_map_color_rgb(sgi_map_color_rgb);
  24.  
  25. private dev_proc_print_page(sgi_print_page);
  26.  
  27. private gx_device_procs sgi_procs =
  28.   prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
  29.           sgi_map_rgb_color, sgi_map_color_rgb);
  30.  
  31. gx_device_printer far_data gs_sgirgb_device =
  32.   sgi_prn_device(sgi_procs, "sgirgb", 3, 24, 255, 255, sgi_print_page);
  33.  
  34. private gx_color_index
  35. sgi_map_rgb_color(gx_device *dev, ushort r, ushort g, ushort b)
  36. {      ushort bitspercolor = dev->color_info.depth / 3;
  37.        ulong max_value = (1 << bitspercolor) - 1;
  38.        return ((r*max_value / gx_max_color_value) << (bitspercolor * 2)) +
  39.           ((g*max_value / gx_max_color_value) << bitspercolor) +
  40.           (b*max_value / gx_max_color_value);
  41. }
  42.  
  43. private int
  44. sgi_map_color_rgb(gx_device *dev, gx_color_index color, ushort prgb[3])
  45. {    ushort bitspercolor = dev->color_info.depth / 3;
  46.     ushort colormask = (1 << bitspercolor) - 1;
  47.  
  48.     prgb[0] = ((color >> (bitspercolor * 2)) & colormask) *
  49.         (ulong)gx_max_color_value / colormask;
  50.     prgb[1] = ((color >> bitspercolor) & colormask) *
  51.         (ulong)gx_max_color_value / colormask;
  52.     prgb[2] = (color & colormask) *
  53.         (ulong)gx_max_color_value / colormask;
  54.     return 0;
  55. }
  56.  
  57. typedef struct sgi_cursor_s {
  58.   gx_device_printer *dev;
  59.   int bpp;
  60.   uint line_size;
  61.   byte *data;
  62.   int lnum;
  63. } sgi_cursor;
  64.  
  65. private int
  66. sgi_begin_page(gx_device_printer *bdev, FILE *pstream, sgi_cursor _ss *pcur)
  67. {
  68.      uint line_size = gdev_mem_bytes_per_scan_line((gx_device_printer*)bdev);
  69.      byte *data = (byte*)gs_malloc(line_size, 1, "sgi_begin_page");
  70.      IMAGE *header= (IMAGE*)gs_malloc(sizeof(IMAGE),1,"sgi_begin_page");
  71.      char filler= '\0';
  72.      int i;
  73.  
  74.      if ((data == (byte*)0)||(header == (IMAGE*)0)) return -1;
  75.  
  76.      bzero(header,sizeof(IMAGE));
  77.      header->imagic = IMAGIC;
  78.      header->type = RLE(1);
  79.      header->dim = 3;
  80.      header->xsize=bdev->width;
  81.      header->ysize=bdev->height;
  82.      header->zsize=3;
  83.      header->min_color  = 0;
  84.      header->max_color  = bdev->color_info.max_color;
  85.      header->wastebytes = 0;
  86.      strncpy(header->name,"gs picture",80);
  87.      header->colormap = CM_NORMAL;
  88.      header->dorev=0;
  89.      fwrite(header,sizeof(IMAGE),1,pstream);
  90.      for (i=0; i<512-sizeof(IMAGE); i++) fputc(filler,pstream);
  91.      pcur->dev = bdev;
  92.      pcur->bpp = bdev->color_info.depth;
  93.      pcur->line_size = line_size;
  94.      pcur->data = data;
  95.      return 0;
  96. }
  97.  
  98. private int
  99. sgi_next_row(sgi_cursor _ss *pcur)
  100. {    if (pcur->lnum < 0)
  101.        return 1;
  102.      gdev_prn_copy_scan_lines((gx_device_printer*)pcur->dev,
  103.                   pcur->lnum--, pcur->data, pcur->line_size);
  104.      return 0;
  105. }
  106.  
  107. #define bdev ((gx_device_printer *)pdev)
  108.  
  109. private int
  110. sgi_print_page(gx_device_printer *pdev, FILE *pstream)
  111. {      sgi_cursor cur;
  112.        int code = sgi_begin_page(bdev, pstream, &cur);
  113.        uint bpe, mask;
  114.        int separation;
  115.        long *rowsizes=(long*)gs_malloc(4,3*bdev->height,"sgi_print_page");
  116.        byte *edata ;
  117.        long lastval; byte*sptr;
  118.        int rownumber;
  119. #define aref2(a,b) a*bdev->height+b
  120.        edata =  (byte*)gs_malloc(cur.line_size, 1, "sgi_begin_page");
  121.        if((code<0)||(rowsizes==(long*)NULL)||(edata==(byte*)NULL)) return(-1);
  122.        fwrite(rowsizes,sizeof(long),3*bdev->height,pstream); /* rowstarts */
  123.        fwrite(rowsizes,sizeof(long),3*bdev->height,pstream); /* rowsizes */
  124.        lastval = 512+sizeof(long)*6*bdev->height;
  125.        fseek(pstream,lastval,0);
  126.        for (separation=0; separation < 3; separation++)
  127.      {
  128.        cur.lnum = cur.dev->height-1;
  129.        rownumber = 0;
  130.        bpe = cur.bpp/3;
  131.        mask = (1<<bpe) - 1;
  132.        while ( !(code=sgi_next_row(&cur)))
  133.          { byte *bp;
  134.            uint x;
  135.            int shift;
  136.            byte *curcol=cur.data;
  137.            byte *startcol=edata;
  138.            int count;
  139.            byte todo, cc;
  140.            byte *iptr, *sptr, *optr, *ibufend;
  141.            for (bp = cur.data, x=0, shift = 8 - cur.bpp;
  142.             x < bdev->width;
  143.             )
  144.          { ulong pixel = 0;
  145.            uint r, g, b;
  146.            switch (cur.bpp >> 3)
  147.              {
  148.              case 3: pixel = (ulong)*bp << 16; bp++;
  149.              case 2: pixel += (uint)*bp << 8; bp++;
  150.              case 1: pixel += *bp; bp++; break;
  151.              case 0: pixel = *bp >> shift;
  152.                if ((shift-=cur.bpp) < 0)
  153.              bp++, shift += 8; break;
  154.              }
  155.            ++x;
  156.            b = pixel & mask; pixel >>= bpe;
  157.            g = pixel & mask; pixel >>= bpe;
  158.            r = pixel & mask;
  159.            switch(separation)
  160.              {
  161.              case 0: *curcol++=r; break;
  162.              case 1: *curcol++=g; break;
  163.              case 2: *curcol++=b; break;
  164.              }
  165.          }
  166.            iptr=cur.data;
  167.            optr=startcol;
  168.            ibufend=curcol-1;
  169.            while(iptr<ibufend) {
  170.          sptr = iptr;                        
  171.          iptr += 2;
  172.          while((iptr<ibufend)&&((iptr[-2]!=iptr[-1])||(iptr[-1]!=iptr[0])))
  173.            iptr++;
  174.          iptr -= 2;
  175.          count = iptr-sptr;
  176.          while(count) {
  177.            todo = count>126 ? 126:count;
  178.            count -= todo;
  179.            *optr++ = 0x80|todo;
  180.            while(todo--)
  181.              *optr++ = *sptr++;
  182.          }
  183.          sptr = iptr;
  184.          cc = *iptr++;
  185.          while( (iptr<ibufend) && (*iptr == cc) )
  186.            iptr++;
  187.          count = iptr-sptr;
  188.          while(count) {
  189.            todo = count>126 ? 126:count;
  190.            count -= todo;
  191.            *optr++ = todo;
  192.            *optr++ = cc;
  193.          }
  194.            }
  195.                *optr++ = 0;
  196.            rowsizes[aref2(separation,rownumber++)] = optr-startcol;
  197.            fwrite(startcol,1,optr-startcol,pstream);
  198.          }
  199.      }
  200.        fseek(pstream,512L,0);
  201.        for(separation=0; separation<3; separation++)
  202.      for(rownumber=0; rownumber<bdev->height; rownumber++)
  203.        {fputc((char)(lastval>>24),pstream);
  204.         fputc((char)(lastval>>16),pstream);
  205.         fputc((char)(lastval>>8),pstream);
  206.         fputc((char)(lastval),pstream);
  207.         lastval+=rowsizes[aref2(separation,rownumber)];}
  208.        for(separation=0; separation<3; separation++)
  209.      for(rownumber=0; rownumber<bdev->height; rownumber++)
  210.        {lastval=rowsizes[aref2(separation,rownumber)];
  211.         fputc((char)(lastval>>24),pstream);
  212.         fputc((char)(lastval>>16),pstream);
  213.         fputc((char)(lastval>>8),pstream);
  214.         fputc((char)(lastval),pstream);}
  215.        gs_free((char*)cur.data, cur.line_size, 1,
  216.          "sgi_print_page(done)");
  217.        gs_free((char*)edata, cur.line_size, 1, "sgi_print_page(done)");
  218.        gs_free((char*)rowsizes,4,3*bdev->height,"sgi_print_page(done)");
  219.        return (code < 0 ? code : 0);
  220. }
  221.